/*
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package fr.loof.fonzie.parsers;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.Query;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import fr.loof.fonzie.PersistenceQuery;
import fr.loof.fonzie.keywords.Aggregate;

public class JPQLPersistenceQuery implements PersistenceQuery
{
    private static Logger logger = LoggerFactory.getLogger( JPQLPersistenceQuery.class );

    private Class entity;

    private StringBuilder jpql = new StringBuilder();

    private List<String> parameters = new LinkedList<String>();
    private List<Class> types = new LinkedList<Class>();

    /**
     * {@inheritDoc}
     * @see fr.loof.fonzie.PersistenceQuery#parameters()
     */
    public Iterator<String> parameters()
    {
        return parameters.iterator();
    }

    public JPQLPersistenceQuery( Class entity, Aggregate aggregate )
    {
        super();
        this.entity = entity;
        append( "select " );
        logger.trace( "applying aggregate {}", aggregate );
        append( aggregate.apply( "e" ) );
        append( " from " ).append( entity.getSimpleName() ).append( " e" );
    }

    public JPQLPersistenceQuery( Class entity, String jpql )
    {
        super();
        this.entity = entity;
        append( jpql );
    }

    public void add( String name, Class type )
    {
        parameters.add( name );
        types.add( null );
    }

    public StringBuilder append( String str )
    {
        return jpql.append( str );
    }

    public String toString()
    {
        return jpql.toString();
    }

    /**
     * {@inheritDoc}
     * @see fr.loof.fonzie.PersistenceQuery#getEntity()
     */
    public Class getEntity()
    {
        return entity;
    }

    /**
     * {@inheritDoc}
     * @see fr.loof.fonzie.PersistenceQuery#createQuery(javax.persistence.EntityManager)
     */
    public Query createQuery( EntityManager entityManager )
    {
        return entityManager.createQuery( jpql.toString() );
    }
}